package com.kyleswebspace.propertyanalyzer.gui;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

import com.kyleswebspace.parser.FieldParser;
import com.kyleswebspace.propertyanalyzer.config.ArcaFont;
import com.kyleswebspace.propertyanalyzer.config.BorderBox;
import com.kyleswebspace.propertyanalyzer.config.ColorBox;
import com.kyleswebspace.propertyanalyzer.model.DataModel;

public class KeyIndicatorsPanel extends JPanel implements Updateable,
		KeyListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7653617893484776372L;

	private DataModel dm;
	private FocusMediator fm;

	ImageIcon greenLight, redLight, yellowLight;
	private JLabel actualLabel, targetLabel;
	private JLabel costPerDoorLabel;
	private JTextField costPerDoorField;
	private JTextField costPerDoorFieldB;
	private JLabel costPerDoorLight;
	private JLabel gRMultiplierLabel;
	private JTextField gRMultiplierField;
	private JTextField gRMultiplierFieldB;
	private JLabel gRMultiplierLight;
	private JLabel capRateLabel;
	private JTextField capRateField;
	private JTextField capRateFieldB;
	private JLabel capRateLight;
	private JLabel cashOnCashReturnLabel;
	private JTextField cashOnCashReturnField;
	private JLabel roiPPDLabel;
	private JTextField roiPPDField;
	private JLabel roiPPDGrowthLabel;
	private JTextField roiPPDGrowthField;
	private JTextField roiPPDGrowthFieldB;
	private JLabel roiPPDGrowthLight;
	private JLabel monthlyProfPerDoorLabel;
	private JTextField monthlyProfPerDoorField;
	private JTextField monthlyProfPerDoorFieldB;
	private JLabel monthlyProfPerDoorLight;
	private JLabel debtCoverageRatioLabel;
	private JTextField debtCoverageRatioField;
	private JTextField debtCoverageRatioFieldB;
	private JLabel debtCoverageRatioLight;
	private JLabel paybackPeriodLabel;
	private JTextField paybackPeriodField;
	private JTextField paybackPeriodFieldB;

	private Color innerPanelColor = ColorBox.innerPanelColor;
	private Color editableColor = ColorBox.fieldColor;
	private Font appFont = ArcaFont.appFont;

	public KeyIndicatorsPanel(DataModel dm, FocusMediator fm) {
		this.dm = dm;
		this.fm = fm;
		dm.register(this);

		loadImages();

		this.setLayout(new GridBagLayout());
		TitledBorder title;
		title = BorderFactory.createTitledBorder("Key Indicators");
		this.setBorder(title);
		this.setBackground(innerPanelColor);

		GridBagConstraints constraints = new GridBagConstraints();
		constraints.ipadx = 20; // PADDING

		// top labels
		actualLabel = new JLabel("Actual ");
		actualLabel.setFont(appFont);
		actualLabel.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridx = 3;
		constraints.gridy = 0;
		constraints.gridwidth = 1;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(actualLabel, constraints);
		targetLabel = new JLabel("Target ");
		targetLabel.setFont(appFont);
		targetLabel.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridx = 4;
		constraints.gridy = 0;
		constraints.gridwidth = 1;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(targetLabel, constraints);

		// cost per door
		costPerDoorLabel = new JLabel("Cost Per Door");
		costPerDoorLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(costPerDoorLabel, constraints);
		costPerDoorLight = new JLabel(greenLight);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		this.add(costPerDoorLight, constraints);
		costPerDoorField = new JTextField(4);
		costPerDoorField.addFocusListener(this);
		costPerDoorField.setFocusable(false);
		costPerDoorField.setFont(appFont);
		costPerDoorField.setBorder(BorderBox.fieldBorder);
		costPerDoorField
				.setToolTipText("<html>Aim for $50K/door or less but<br/>"
						+ "consider properties with higher<br/>"
						+ "values. This is just a guideline to<br/>"
						+ "help you quickly determine if this<br/>"
						+ "property may cash flow.<br/><br/>" + "</html>");
		costPerDoorFieldB = new JTextField(4);
		fm.setCostPerDoorField(costPerDoorFieldB);
		costPerDoorFieldB.addFocusListener(this);
		costPerDoorFieldB.addKeyListener(this);
		costPerDoorFieldB.setBackground(editableColor);
		costPerDoorFieldB.setFont(appFont);
		costPerDoorFieldB.setBorder(BorderBox.fieldBorder);
		costPerDoorFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		costPerDoorField.setHorizontalAlignment(JTextField.RIGHT);
		costPerDoorFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(costPerDoorField, constraints);
		constraints.gridx = 4;
		this.add(costPerDoorFieldB, constraints);
		constraints.gridx = 5;

		// gross rent multiplier
		gRMultiplierLabel = new JLabel("Gross Rent Multiplier (GRM)     ");
		gRMultiplierLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 2;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(gRMultiplierLabel, constraints);
		gRMultiplierLight = new JLabel(greenLight);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		this.add(gRMultiplierLight, constraints);
		gRMultiplierField = new JTextField(4);
		gRMultiplierField.addFocusListener(this);
		gRMultiplierField.setFocusable(false);
		gRMultiplierField.setFont(appFont);
		gRMultiplierField.setBorder(BorderBox.fieldBorder);
		gRMultiplierField
				.setToolTipText("<html>This value is determined by<br/>"
						+ "dividing the gross rental income<br/>"
						+ "into the value of the property. It is<br/>"
						+ "simply a guideline similar to a cap<br/>"
						+ "rate for quickly determining the<br/>"
						+ "approximate value of a property.</html>");
		gRMultiplierFieldB = new JTextField(4);
		fm.setgRMField(gRMultiplierFieldB);
		gRMultiplierFieldB.addFocusListener(this);
		gRMultiplierFieldB.addKeyListener(this);
		gRMultiplierFieldB.setBackground(editableColor);
		gRMultiplierFieldB.setFont(appFont);
		gRMultiplierFieldB.setBorder(BorderBox.fieldBorder);
		gRMultiplierFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		gRMultiplierField.setHorizontalAlignment(JTextField.RIGHT);
		gRMultiplierFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(gRMultiplierField, constraints);
		constraints.gridx = 4;
		this.add(gRMultiplierFieldB, constraints);
		constraints.gridx = 5;

		// cap rate
		capRateLabel = new JLabel("Cap Rate");
		capRateLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 3;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(capRateLabel, constraints);
		capRateLight = new JLabel(greenLight);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		this.add(capRateLight, constraints);
		capRateField = new JTextField(4);
		capRateField.addFocusListener(this);
		capRateField.setFocusable(false);
		capRateField.setFont(appFont);
		capRateField.setBorder(BorderBox.fieldBorder);
		capRateField.setToolTipText("<html><b>CAP = NOI/Price</b><br/>"
				+ "Capitalization rate (or \"cap rate\") is the ratio<br/>"
				+ "between the net operating income produced<br/>"
				+ "by an asset and its capital cost (the original<br/>"
				+ "price paid to buy the asset) or alternatively its<br/>"
				+ "current market value.</html>");
		capRateFieldB = new JTextField(4);
		fm.setCapRateField(capRateFieldB);
		capRateFieldB.addFocusListener(this);
		capRateFieldB.addKeyListener(this);
		capRateFieldB.setBackground(editableColor);
		capRateFieldB.setFont(appFont);
		capRateFieldB.setBorder(BorderBox.fieldBorder);
		capRateFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		capRateField.setHorizontalAlignment(JTextField.RIGHT);
		capRateFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(capRateField, constraints);
		constraints.gridx = 4;
		this.add(capRateFieldB, constraints);
		constraints.gridx = 5;

		// cash on cash return
		cashOnCashReturnLabel = new JLabel("Cash on Cash Return");
		cashOnCashReturnLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 4;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(cashOnCashReturnLabel, constraints);
		cashOnCashReturnField = new JTextField(4);
		cashOnCashReturnField.addFocusListener(this);
		cashOnCashReturnField.setFocusable(false);
		cashOnCashReturnField.setBorder(BorderBox.fieldBorder);
		cashOnCashReturnField
				.setToolTipText("<html>The amount (cashflow only), expressed as a<br/>"
						+ "percentage, that is earned on the total cash<br/>"
						+ "invested. This value is your basic calculation and<br/>"
						+ "can vary greatly depending on how you manage<br/>"
						+ "your property and is calculated using before tax<br/>"
						+ "values. After tax values vary to greatly because<br/>"
						+ "of peoples personal taxable situations.</html>");
		cashOnCashReturnField.setFont(appFont);
		cashOnCashReturnField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(cashOnCashReturnField, constraints);
		constraints.gridx = 4;

		// ROI + PPD
		roiPPDLabel = new JLabel("ROI + PPD");
		roiPPDLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 5;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(roiPPDLabel, constraints);
		roiPPDField = new JTextField(4);
		roiPPDField.addFocusListener(this);
		roiPPDField.setFocusable(false);
		roiPPDField.setFont(appFont);
		roiPPDField.setBorder(BorderBox.fieldBorder);
		roiPPDField.setToolTipText("<html>The amount (including principal<br/>"
				+ "paid in the first year), expressed<br/>"
				+ "as a percentage, that is earned<br/>"
				+ "on the total cash invested.</html>");
		roiPPDField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(roiPPDField, constraints);
		constraints.gridx = 4;

		// ROI + PPD + 3% growth
		roiPPDGrowthLabel = new JLabel("ROI + PPD + 3% Growth");
		roiPPDGrowthLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 6;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(roiPPDGrowthLabel, constraints);
		roiPPDGrowthLight = new JLabel(redLight);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		this.add(roiPPDGrowthLight, constraints);
		roiPPDGrowthField = new JTextField(4);
		roiPPDGrowthField.addFocusListener(this);
		roiPPDGrowthField.setFocusable(false);
		roiPPDGrowthField.setFont(appFont);
		roiPPDGrowthField.setBorder(BorderBox.fieldBorder);
		roiPPDGrowthField
				.setToolTipText("<html>The amount (including principal paid<br/>"
						+ "and appreciation of property), that is<br/>"
						+ "earned on the total cash invested.</html>");
		roiPPDGrowthFieldB = new JTextField(4);
		fm.setRoiPPDGrowthField(roiPPDGrowthFieldB);
		roiPPDGrowthFieldB.addFocusListener(this);
		roiPPDGrowthFieldB.addKeyListener(this);
		roiPPDGrowthFieldB.setBackground(editableColor);
		roiPPDGrowthFieldB.setFont(appFont);
		roiPPDGrowthFieldB.setBorder(BorderBox.fieldBorder);
		roiPPDGrowthFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		roiPPDGrowthField.setHorizontalAlignment(JTextField.RIGHT);
		roiPPDGrowthFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(roiPPDGrowthField, constraints);
		constraints.gridx = 4;
		this.add(roiPPDGrowthFieldB, constraints);
		constraints.gridx = 5;

		// avg. monthly profit/door
		monthlyProfPerDoorLabel = new JLabel("Monthly Profit / Door");
		monthlyProfPerDoorLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 7;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(monthlyProfPerDoorLabel, constraints);
		monthlyProfPerDoorLight = new JLabel(redLight);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		this.add(monthlyProfPerDoorLight, constraints);
		monthlyProfPerDoorField = new JTextField(4);
		monthlyProfPerDoorField.addFocusListener(this);
		monthlyProfPerDoorField.setFocusable(false);
		monthlyProfPerDoorField.setFont(appFont);
		monthlyProfPerDoorField.setBorder(BorderBox.fieldBorder);
		monthlyProfPerDoorField
				.setToolTipText("<html>The average profit generated per<br/>"
						+ "door of the investment property.</html>");
		monthlyProfPerDoorFieldB = new JTextField(4);
		fm.setMonthlyProfPerDoorField(monthlyProfPerDoorFieldB);
		monthlyProfPerDoorFieldB.addFocusListener(this);
		monthlyProfPerDoorFieldB.addKeyListener(this);
		monthlyProfPerDoorFieldB.setBackground(editableColor);
		monthlyProfPerDoorFieldB.setFont(appFont);
		monthlyProfPerDoorFieldB.setBorder(BorderBox.fieldBorder);
		monthlyProfPerDoorFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		monthlyProfPerDoorField.setHorizontalAlignment(JTextField.RIGHT);
		monthlyProfPerDoorFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(monthlyProfPerDoorField, constraints);
		constraints.gridx = 4;
		this.add(monthlyProfPerDoorFieldB, constraints);
		constraints.gridx = 5;

		// debt coverage ratio
		debtCoverageRatioLabel = new JLabel("Debt Coverage Ratio");
		debtCoverageRatioLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 8;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(debtCoverageRatioLabel, constraints);
		debtCoverageRatioLight = new JLabel(redLight);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		this.add(debtCoverageRatioLight, constraints);
		debtCoverageRatioField = new JTextField(4);
		debtCoverageRatioField.addFocusListener(this);
		debtCoverageRatioField.setFocusable(false);
		debtCoverageRatioField.setFont(appFont);
		debtCoverageRatioField.setBorder(BorderBox.fieldBorder);
		debtCoverageRatioField
				.setToolTipText("<html><b>DCR Coverage=NOI/ADS</b><br/>"
						+ "Tells us how well the cashflow can pay for the debt.<br/><br/>"
						+ "Different lenders may have different means of<br/>"
						+ "calculation DCR and or they may also have<br/>"
						+ "different acceptable minimum values. Check with your<br/>"
						+ "lender to better understand what they are<br/>"
						+ "looking for.</html");
		debtCoverageRatioFieldB = new JTextField(4);
		fm.setDebtCoverageField(debtCoverageRatioFieldB);
		debtCoverageRatioFieldB.addFocusListener(this);
		debtCoverageRatioFieldB.addKeyListener(this);
		debtCoverageRatioFieldB.setFont(appFont);
		debtCoverageRatioFieldB.setBorder(BorderBox.fieldBorder);
		debtCoverageRatioFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		debtCoverageRatioFieldB.setBackground(editableColor);
		debtCoverageRatioField.setHorizontalAlignment(JTextField.RIGHT);
		debtCoverageRatioFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(debtCoverageRatioField, constraints);
		constraints.gridx = 4;
		this.add(debtCoverageRatioFieldB, constraints);
		constraints.gridx = 5;

		// payback period
		paybackPeriodLabel = new JLabel("Payback Period");
		paybackPeriodLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 9;
		constraints.gridwidth = 2;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(paybackPeriodLabel, constraints);
		paybackPeriodField = new JTextField(4);
		paybackPeriodField.addFocusListener(this);
		paybackPeriodField.setFocusable(false);
		paybackPeriodField.setFont(appFont);
		paybackPeriodField.setBorder(BorderBox.fieldBorder);
		paybackPeriodField
				.setToolTipText("<html>The length of time it takes for the<br/>"
						+ "accumulated net returns earned from<br/>"
						+ "an investment to equal the original<br/>"
						+ "investment.</html>");
		paybackPeriodFieldB = new JTextField(4);
		fm.setPaybackPeriodField(paybackPeriodFieldB);
		paybackPeriodFieldB.addFocusListener(this);
		paybackPeriodFieldB.addKeyListener(this);
		paybackPeriodFieldB.setFont(appFont);
		paybackPeriodFieldB.setBorder(BorderBox.fieldBorder);
		paybackPeriodFieldB.setToolTipText("<html>"
				+ "These preset target values are<br/>"
				+ "guidelines to help indicate how viable<br/>"
				+ "a property is for cash flow purposes. If<br/>"
				+ "a property meets or exceeds these<br/>"
				+ "expectations then there is a very good<br/>"
				+ "chance that it will cash flow. You may<br/>"
				+ "enter your own target values but keep<br/>"
				+ "in mind that they are your values and<br/>"
				+ "not those of ARCA Real Estate<br/>"
				+ "Investments Inc. and as the<br/>"
				+ "disclaimer states you will be<br/>"
				+ "responsible for any purchase<br/>"
				+ "you make based upon these results." + "</html>");
		paybackPeriodFieldB.setBackground(editableColor);
		paybackPeriodField.setHorizontalAlignment(JTextField.RIGHT);
		paybackPeriodFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(paybackPeriodField, constraints);
		constraints.gridx = 4;
		this.add(paybackPeriodFieldB, constraints);

		updateFields();
	}

	public void updateModel() {
		dm.setCostPerDoorTarget(FieldParser.parseInteger(this.costPerDoorFieldB
				.getText().replaceAll(",", "")));
		dm.setGrossRentMultiplierTarget(FieldParser
				.parseInteger(this.gRMultiplierFieldB.getText().replaceAll(",",
						"")));
		dm.setCapRateTarget(FieldParser.parseInteger(this.capRateFieldB
				.getText().replaceAll(",", "")));
		dm.setRoiPPDGrowthTarget(FieldParser
				.parseInteger(this.roiPPDGrowthFieldB.getText().replaceAll(",",
						"")));
		dm.setAvgProfitPerDoorTarget(FieldParser
				.parseInteger(this.monthlyProfPerDoorFieldB.getText()
						.replaceAll(",", "")));
		dm.setDebtCoverageRatioTarget(FieldParser
				.parseInteger(this.debtCoverageRatioFieldB.getText()
						.replaceAll(",", "")));
		dm.setPaybackPeriodTarget(FieldParser
				.parseInteger(this.paybackPeriodFieldB.getText().replaceAll(
						",", "")));

		dm.updateInterface();
	}

	public void updateFields() {
		this.costPerDoorField.setText(dm.getCostPerDoorActual());
		this.costPerDoorFieldB.setText(dm.getCostPerDoorTarget());
		this.gRMultiplierField.setText(dm.getGrossRentMultiplierActual());
		this.gRMultiplierFieldB.setText(dm.getGrossRentMultiplierTarget());
		this.capRateField.setText(dm.getCapRateActual()
				+ (dm.getCapRateActual().equalsIgnoreCase("n/a")
						|| capRateField.getText().equalsIgnoreCase("") ? ""
						: "%"));
		this.capRateFieldB.setText(dm.getCapRateTarget() + "%");
		this.cashOnCashReturnField.setText(dm.getCashOnCashReturnActual());
		this.roiPPDGrowthLabel.setText(dm.getRoiPPDGrowthLabel());
		this.roiPPDField.setText(dm.getRoiPPDActual()
				+ (dm.getRoiPPDActual().equalsIgnoreCase("n/a")
						|| roiPPDField.getText().equalsIgnoreCase("") ? ""
						: "%"));
		this.roiPPDGrowthField
				.setText(dm.getRoiPPDGrowthActual()
						+ (dm.getRoiPPDGrowthActual().equalsIgnoreCase("n/a")
								|| roiPPDGrowthField.getText()
										.equalsIgnoreCase("") ? "" : "%"));
		this.roiPPDGrowthFieldB.setText(dm.getRoiPPDGrowthTarget() + "%");
		this.monthlyProfPerDoorField.setText(dm.getAvgProfitPerDoorActual());
		this.monthlyProfPerDoorFieldB.setText(dm.getAvgProfitPerDoorTarget());
		this.debtCoverageRatioField.setText(dm.getDebtCoverageRatioActual());
		this.debtCoverageRatioFieldB.setText(dm.getDebtCoverageRatioTarget());
		this.paybackPeriodField.setText(dm.getPaybackPeriodActual());
		this.paybackPeriodFieldB.setText(dm.getPaybackPeriodTarget() + " yrs");

		if (!dm.getCostPerDoorActual().equalsIgnoreCase("n/a")) {
			if (Integer.parseInt(dm.getCostPerDoorActual()) < Integer
					.parseInt(dm.getCostPerDoorTarget()))
				costPerDoorLight.setIcon(greenLight);
			else if (Integer.parseInt(dm.getCostPerDoorActual()) < Integer
					.parseInt(dm.getCostPerDoorTarget()))
				System.out.println();
			else
				costPerDoorLight.setIcon(redLight);
		} else {
			costPerDoorLight.setIcon(redLight);
		}

		if (!dm.getGrossRentMultiplierActual().equalsIgnoreCase("n/a")) {
			if (Double.parseDouble(dm.getGrossRentMultiplierActual()) < Double
					.parseDouble(dm.getGrossRentMultiplierTarget()))
				gRMultiplierLight.setIcon(greenLight);
			else
				gRMultiplierLight.setIcon(redLight);
		} else {
			gRMultiplierLight.setIcon(redLight);
		}

		if (!dm.getCapRateActual().equalsIgnoreCase("n/a")) {
			if (Double.parseDouble(dm.getCapRateActual()) > Double
					.parseDouble(dm.getCapRateTarget()))
				capRateLight.setIcon(greenLight);
			else
				capRateLight.setIcon(redLight);
		} else {
			capRateLight.setIcon(redLight);
		}

		if (!dm.getRoiPPDGrowthActual().equalsIgnoreCase("n/a")) {
			if (Double.parseDouble(dm.getRoiPPDGrowthActual()) > Double
					.parseDouble(dm.getRoiPPDGrowthTarget()))
				roiPPDGrowthLight.setIcon(greenLight);
			else
				roiPPDGrowthLight.setIcon(redLight);
		} else {
			roiPPDGrowthLight.setIcon(redLight);
		}

		if (!dm.getAvgProfitPerDoorActual().equalsIgnoreCase("n/a")) {
			if (Double.parseDouble(dm.getAvgProfitPerDoorActual()) > Double
					.parseDouble(dm.getAvgProfitPerDoorTarget()))
				monthlyProfPerDoorLight.setIcon(greenLight);
			else
				monthlyProfPerDoorLight.setIcon(redLight);
		} else {
			monthlyProfPerDoorLight.setIcon(redLight);
		}

		if (!dm.getDebtCoverageRatioActual().equalsIgnoreCase("n/a")) {
			if (Double.parseDouble(dm.getDebtCoverageRatioActual()) > Double
					.parseDouble(dm.getDebtCoverageRatioTarget()))
				debtCoverageRatioLight.setIcon(greenLight);
			else
				debtCoverageRatioLight.setIcon(redLight);
		} else {
			debtCoverageRatioLight.setIcon(redLight);
		}

	}

	private void loadImages() {
		redLight = new ImageIcon(getClass().getResource("redLight.gif"));
		greenLight = new ImageIcon(getClass().getResource("greenLight.gif"));
		yellowLight = new ImageIcon(getClass().getResource("yellowLight.gif"));
	}

	@Override
	public void focusGained(FocusEvent e) {
		if (e.getSource() instanceof JTextField) {
			JTextField focusedField = (JTextField) e.getSource();
			focusedField.selectAll();
		}

	}

	@Override
	public void focusLost(FocusEvent e) {
		updateModel();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getSource() == costPerDoorFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getgRMField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getApplyMortInsFieldA().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getLawnField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		} else if (e.getSource() == gRMultiplierFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getCapRateField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getCostPerDoorField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getLicensesField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		} else if (e.getSource() == capRateFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getRoiPPDGrowthField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getgRMField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getAccountingField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		} else if (e.getSource() == roiPPDGrowthFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getMonthlyProfPerDoorField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getCapRateField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPoolField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		} else if (e.getSource() == monthlyProfPerDoorFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getDebtCoverageField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getRoiPPDGrowthField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getElevatorField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		} else if (e.getSource() == debtCoverageRatioFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getPaybackPeriodField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getMonthlyProfPerDoorField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPestControlField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		} else if (e.getSource() == paybackPeriodFieldB) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getPercentPPAField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getDebtCoverageField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getReplacementsField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getLessCashBackField().requestFocus();
			}
		}
		if (e.getKeyCode() == KeyEvent.VK_ENTER) {
			updateModel();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {

	}

	@Override
	public void keyTyped(KeyEvent e) {

	}
}
